package webjoch.process;

import org.rsbuddy.tabs.Inventory;
import org.rsbuddy.tabs.Magic;

import com.rsbuddy.script.methods.Players;
import com.rsbuddy.script.wrappers.Tile;

import webjoch.Main;
import webjoch.methods.Links;
import webjoch.methods.Rooms;
import webjoch.misc.Functions;
import webjoch.misc.PaintMap;
import webjoch.wrappers.Door;
import webjoch.wrappers.Explorer;
import webjoch.wrappers.Link;
import webjoch.wrappers.Room;
import webjoch.wrappers.Task;

/**
 * When the local room is cleared, travel to the next rooms
 * @author Webjoch
 *
 */
public class Traveling {	
	public static int loop(){		
		Room room = Rooms.getLocalRoom();
		
		//Open doors && add key doors from current room
		for (Door door : room.getDoors()){
			if (door.getType() == Door.Type.KEY && door.isLocked() && !Functions.inArray(Main.getDungeon().getKeyDoors(), door)){
				Main.getDungeon().addKeyDoor(door);
			}
			if(door.canOpen()){
				Main.setStatus("Open door");
				door.open();
				return 1;
			}
		}
				
		//Add key doors from linked rooms
		for (Link link : Links.getRoomLinks(room)){
			for (Door door : link.getLinkedRoom().getDoors()){
				if (door.getType() == Door.Type.KEY && door.isLocked() && !Functions.inArray(Main.getDungeon().getKeyDoors(), door)) Main.getDungeon().addKeyDoor(door);
			}
		}
				
		//add tasks from linked rooms
		Task task;
		for (Link link : Links.getRoomLinks(room)){
			if (link.getLinkedRoom().getType() == Room.Type.BOSS){
				if (link.getLinkedRoom().getBoss() == null){
					Main.getDungeon().stop("Don't know the boss");
					return 1;
				}
				Main.getDungeon().setBoss(link.getLinkedRoom().getBoss());
			}
			for (Door door : link.getLinkedRoom().getDoors()){
				if (door.getType() == Door.Type.SKILL && !door.isOpen() && door.getNeededSkillItem()[0] != 0 && !Inventory.containsOneOf(door.getNeededSkillItem())){
					task = new Task(link.getLinkedRoom());
					task.setItems(door.getNeededSkillItem());
					Main.getDungeon().removeTask(task, false);
					Main.getDungeon().addTask(task);
				}
			}
			if (link.getLinkedRoom().getKey() != null
					|| link.getLinkedRoom().canOpenDoors()
					|| link.getLinkedRoom().getKey() != null
					|| link.getLinkedRoom().isGuardianRoom() && link.getLinkedRoom().containsEnemies()){
				Main.getDungeon().removeTask(new Task(link.getLinkedRoom()), false);
				Main.getDungeon().addTask(new Task(link.getLinkedRoom()));
			}
		}
		
		//Enter doors
		for (Link link : Links.getRoomLinks(room)){
			if (Main.getDungeon().ignoreRoom(link.getLinkedRoom())) continue;
			if (link.getLinkedRoom().canOpenDoors()
					|| link.getLinkedRoom().getKey() != null
					|| link.getLinkedRoom().isGuardianRoom() && link.getLinkedRoom().containsEnemies() 
					|| link.getLinkedRoom().getType() == Room.Type.PUZZLE && !link.getLinkedRoom().getPuzzle().isFinished()){
				
				if (link.getLinkedRoom().getType() == Room.Type.PUZZLE && link.getLinkedRoom().getPuzzle().itemNeed().length != 0){
					if (!Inventory.containsAll(link.getLinkedRoom().getPuzzle().itemNeed())){
						task = new Task(link.getLinkedRoom());
						task.setItems(link.getLinkedRoom().getPuzzle().itemNeed());
						Main.getDungeon().removeTask(task, false);
						Main.getDungeon().addTask(task);
						continue;
					}
				}
				Main.setStatus("Enter room");
				room.getDoor(link.getRotation()).enter();
				return 1;
			}
		}
		
		//Travel to key doors
		for (Door keyDoor : Main.getDungeon().getKeyDoors()){
			if (Inventory.contains(keyDoor.getKeyId())){
				if (travel(keyDoor.getLocation())){
					Main.setStatus("To key door");
					return 1;
				}
			}
		}
		
		//Going to base to buy items
		int neededItemsAmount = 0;
		for (Task task1 : Main.getDungeon().getTasks()){
			if (task1.getNeededItems()[0] != 0 && !Inventory.containsAll(task1.getNeededItems())){
				neededItemsAmount++;
				continue;
			}
			if (travel(task1.getRoom().getLocation())) return 1;
		}
				
		if (neededItemsAmount > 0){
			if (!room.containsEnemies() && !Rooms.getBase().inRoom()){
				Main.setStatus("Home teleport");
				Magic.castSpell(Magic.Dungeoneering.HOME_TELEPORT);
				com.rsbuddy.script.task.Task.sleep(2000);
				for (int i = 0; i < 100; i++){
					if (Players.getLocal().getAnimation() < 0) break;
					com.rsbuddy.script.task.Task.sleep(120);
				}
				return 1;
			}
			if (travel(Main.getDungeon().getBaseLocation())) return 1;
		}
		
		if (Main.getDungeon().getBoss() != null){
			Main.getDungeon().bossTime();
		}
		
		Main.setStatus("Idle");
		return 1;
	}
	
	/**
	 * Travel to the dungeon
	 * @param destination location to travel to
	 * @return returns true if there are doors to enter
	 */
	public static boolean travel(Tile destination){
		Room room = Main.getDungeon().getCurrentRoom();
		Explorer path = new Explorer(room, destination);
		PaintMap.setPath(path);
		if (path.getNext() != null){
			Main.setStatus("Walking to task");
			room.getDoor(path.getNext().getRotation()).enter();
			return true;
		}
		return false;
	}
}